Unit ReadExternalApp;

{
    Copyright (c) 2004-2011 by Marc Weustink and contributors
 
    This example is created in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
}

// This is a 
// WORKING
// demo program that shows
// how to launch an external program
// and read from its output.

// **** Modified to suit captiveportal ****

Interface
 
Uses
  Classes, 
  Process, 
  SysUtils;

Function ExecuteExternalApp(Const aExternalApp : String; Const aParameters : Array Of String): String;
  
Implementation

Function ExecuteExternalApp(Const aExternalApp : String; Const aParameters : Array Of String): String;

Const
  READ_BYTES = 2048;

Var
	lOutputLines: TStringList;
	lMemStream: TMemoryStream;
	lProcess: TProcess;
	lNumBytes: LongInt;
	lBytesRead: LongInt;
	lParameters : TStringList;
	lCtrl : Integer;

Begin
	Try
		Try
			{ Debug } WriteLn('Run external program');
			{ Debug } WriteLn('Parsing parameters.');
			lParameters := TStringList.Create;
			For lCtrl := Low(aParameters) To High(aParameters) Do
				lParameters.Add(aParameters[lCtrl]);
			{ Debug } WriteLn('Done parsing parameters.');
			lMemStream := TMemoryStream.Create;
			lBytesRead := 0;
			lProcess := TProcess.Create(Nil);
			lProcess.Executable := aExternalApp;
			lProcess.Parameters := lParameters;
			lProcess.Options := [ poUsePipes ];
			{ Debug } WriteLn('Starting');
			lProcess.Execute;
			{ Debug } WriteLn('Program is running.');
			While lProcess.Running do
			Begin          
				{ Debug } WriteLn('Creating space.');
				// make sure we have room
				lMemStream.SetSize(lBytesRead + READ_BYTES);
				// try reading it
				{ Debug } WriteLn('Reading program output...');
				lNumBytes := lProcess.Output.Read((lMemStream.Memory + lBytesRead)^, READ_BYTES);
				{ Debug } WriteLn('Done : ', lBytesRead);
				If lNumBytes > 0 Then 
					Inc(lBytesRead, lNumBytes)
				Else 
					Sleep(10); 
			End;
			{ Debug } WriteLn('Program finished, reading standing output...');
			// read last part
			Repeat
				{ Debug } WriteLn('Creating space.');
				// make sure we have room
				lMemStream.SetSize(lBytesRead + READ_BYTES);
				// try reading it
				{ Debug } WriteLn('Reading program output...');
				lNumBytes := lProcess.Output.Read((lMemStream.Memory + lBytesRead)^, READ_BYTES);
				{ Debug } WriteLn('Done : ', lBytesRead);
				If lNumBytes > 0 Then 
					Inc(lBytesRead, lNumBytes);
			Until lNumBytes <= 0;
			{ Debug } WriteLn('Finished. Setting bufffer.');
			lMemStream.SetSize(lBytesRead);
			{ Debug } WriteLn('Translating to string.');
			lOutputLines := TStringList.Create;
			lOutputLines.LoadFromStream(lMemStream);
			Result := lOutputLines.Text;
			{ Debug } WriteLn('Done all.');
		Finally
			FreeAndNil(lParameters);
			FreeAndNil(lOutputLines);
			FreeAndNil(lProcess);
			FreeAndNil(lMemStream);
		End;
	Except
		On E: Exception Do
		Begin
			Result := '';
			{ Debug } WriteLn(E.Message);
		End;
	End;
End;

End.